package com.cloudfast.platform.menu.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloudfast.common.page.Page;
import com.cloudfast.platform.menu.dao.MenuDao;
import com.cloudfast.platform.menu.entity.Menu;

/**
 * @author liuyw
 */
@Service
@Transactional(readOnly = true)
public class MenuService {
    @Autowired
    private MenuDao menuDao;

    @Transactional(readOnly = false)
    public void save(Menu entity) {
        menuDao.saveOrUpdate(entity);
    }

    /**
     * 查询根据id
     *
     * @param id
     * @return
     */
    public Menu findOne(Long id) {
        return this.menuDao.findOne(id);
    }

    /**
     * 根据id 删除
     *
     * @param id
     */
    @Transactional(readOnly = false)
    public void delete(Long id) {
        this.menuDao.deleteById(id);
    }

    /**
     * 分页
     *
     * @param page
     * @param menu
     * @return
     */
    public Page<Menu> findPage(Page<Menu> page, Menu menu) {
        StringBuilder hql = new StringBuilder(" from Menu where 1=1 ");
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotEmpty(menu.getName())) {
            hql.append(" and name=:name");
            params.put("name", menu.getName());
        }
        if (menu.getParentId() != null) {
            hql.append(" and parentId=:parentId");
            params.put("parentId", menu.getParentId());
        }
        hql.append(" and isAdmin='0' ");
        hql.append(" and delFlag='0'  ");

        return this.menuDao.findPage(page, hql.toString(), params);
    }

    /**
     * 查询selectTree
     *
     * @return
     */
    public List<Map<String, Object>> findMenuTree() {
        StringBuilder hql = new StringBuilder(" from Menu where 1=1  and delFlag='0' order by sort ");
        List<Menu> list = this.menuDao.findList(hql.toString());
        List<Map<String, Object>> treeMap = new ArrayList<>();
        for (Menu menu : list) {
            Map<String, Object> treeNode = new HashMap<>();
            treeNode.put("id", menu.getId());
            treeNode.put("pId", menu.getParentId());
            treeNode.put("value", menu.getId().toString());
            treeNode.put("title", menu.getName());
            treeMap.add(treeNode);
        }
        return treeMap;
    }

    /**
     * 查询treeData
     *
     * @param parentId
     * @param hasChildren
     * @return
     */
    public List<Map<String, Object>> findMenuTree(Long parentId, boolean hasChildren) {
        StringBuilder hql = new StringBuilder(" from Menu where 1=1  and delFlag='0'  ");
        hql.append(" and parentId=:parentId");
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", parentId);
        hql.append(" order by type,sort ");
        List<Menu> list = this.menuDao.findList(hql.toString(), params);
        List<Map<String, Object>> treeMap = new ArrayList<>();
        for (Menu menu : list) {
            Map<String, Object> treeNode = new HashMap<>();
            treeNode.put("key", menu.getId().toString());
            treeNode.put("title", menu.getName());
            treeNode.put("parentKey", menu.getParentId().toString());
            treeNode.put("permissionScope", menu.getPermissionScope());
            treeNode.put("disabled", menu.getRouterType().equals("dir_route"));
            if (hasChildren) {
                List<Map<String, Object>> children = findMenuTree(menu.getId(), true);
                treeNode.put("children", children);
            }
            treeMap.add(treeNode);
        }
        return treeMap;
    }

    /**
     * 普通用户查询菜单树
     *
     * @param parentId
     * @param userId
     * @return
     */
    public List<Map<String, Object>> findMenuTree(Long parentId, Long userId, boolean hasChildren) {
        StringBuilder hql = new StringBuilder(
                "select a.id,a.name,a.permission_scope,a.sort,a.type from sys_menu a,(select a.parent_id from sys_menu a,sys_role_menu b,sys_user_role c where (a.id=b.menu_id)  and (c.role_id=b.role_id ) and c.user_id=:userId    GROUP BY a.parent_id) b where a.id =b.parent_id and a.parent_id=:parentId ");
        hql.append(
                "UNION select  a.id,a.name,a.permission_scope,a.sort,a.type  from sys_menu a,sys_role_menu b,sys_user_role c where (a.id=b.menu_id)  and (c.role_id=b.role_id ) and c.user_id=:userId and a.parent_id=:parentId  GROUP BY a.id order by a.type, a.sort");
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", parentId);
        params.put("userId", userId);
        List<Map<String, Object>> list = this.menuDao.nativeQuery(hql.toString(), params);
        List<Map<String, Object>> treeMap = new ArrayList<>();
        for (Map<String, Object> menu : list) {
            Map<String, Object> treeNode = new HashMap<>();
            treeNode.put("key", menu.get("id"));
            treeNode.put("title", menu.get("name"));
            treeNode.put("permissionScope", menu.get("permission_scope"));
            if (hasChildren) {
                List<Map<String, Object>> children = findMenuTree(Long.parseLong(menu.get("id").toString()), userId,
                        true);
                treeNode.put("children", children);
            }
            treeMap.add(treeNode);
        }
        return treeMap;
    }

    /**
     * 根据角色-查询角色包含的菜单
     *
     * @param parentId
     * @param roleId
     * @return
     */
    public List<Map<String, Object>> roleTreeData(Long parentId, Long roleId) {

        StringBuilder hql = new StringBuilder(
                "select * from (select a.id,a.name,a.sort,a.type from sys_menu a,(select a.parent_id from sys_menu a,sys_role_menu b where (a.id=b.menu_id) and b.role_id=:roleId    GROUP BY a.parent_id) b where a.id =b.parent_id and a.parent_id=:parentId ");
        hql.append(
                "UNION select a.id,a.name,a.sort,a.type from sys_menu a,sys_role_menu b where (a.id=b.menu_id) and b.role_id=:roleId and a.parent_id=:parentId ) a GROUP BY a.id order by a.type, a.sort ");
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", parentId);
        params.put("roleId", roleId);
        List<Map<String, Object>> list = this.menuDao.nativeQuery(hql.toString(), params);
        List<Map<String, Object>> treeMap = new ArrayList<>();
        for (Map<String, Object> menu : list) {
            Map<String, Object> treeNode = new HashMap<>();
            treeNode.put("key", menu.get("id"));
            treeNode.put("title", menu.get("name"));
            List<Map<String, Object>> children = roleTreeData(Long.parseLong(menu.get("id").toString()), roleId);
            treeNode.put("children", children);
            treeMap.add(treeNode);
        }
        return treeMap;
    }

    /**
     * 根据父id查询父对象
     *
     * @param parentId
     * @return
     */
    public Menu findByParentId(Long parentId) {
        StringBuilder sql = new StringBuilder("from Menu where parentId=:parentId");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("parentId", parentId);
        return this.menuDao.findList(sql.toString(), params).get(0);
    }

    /**
     * 角色关联的菜单id不含父及
     *
     * @param roleId
     * @return
     */
    public List<Long> roleMenuIds(Long roleId) {
        StringBuilder hql = new StringBuilder(
                "select a.id from sys_menu a,sys_role_menu b where (a.id=b.menu_id) and b.role_id=:roleId  ");
        Map<String, Object> params = new HashMap<>();
        params.put("roleId", roleId);
        List<Map<String, Object>> list = this.menuDao.nativeQuery(hql.toString(), params);
        List<Long> treeMap = new ArrayList<>();
        for (Map<String, Object> menu : list) {
            treeMap.add(Long.parseLong(menu.get("id").toString()));
        }
        return treeMap;
    }

    /**
     * 查询用户拥有的菜单
     *
     * @param parentId
     * @param userId
     * @return
     */
    public List<Map<String, Object>> findUserHasMenu(Long parentId, Long userId) {
        List<Map<String, Object>> menuList = null;
        StringBuilder hql = new StringBuilder("select m  from Menu m,RoleMenu rm,UserRole ur where 1=1 ");
        hql.append(" and m.id=rm.menuId and rm.roleId=ur.roleId ");
        hql.append(" and m.parentId =:parentId  and ur.userId =:userId ");
        hql.append(" and  m.type='1' group by m.id order by m.type asc,m.sort asc");
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", parentId);
        params.put("userId", userId);
        List<Menu> list = this.menuDao.findList(hql.toString(), params);
        if (list != null && list.size() > 0) {
            menuList = new ArrayList<>();
            for (Menu menu : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("index", menu.getGradeCode());
                map.put("menuName", menu.getName());
                map.put("icon", menu.getIcon());
                map.put("routerType", menu.getRouterType());
                map.put("scope", menu.getPermissionScope());
                if (StringUtils.isNotEmpty(menu.getPath())) {
                    map.put("router", menu.getPath());
                    map.put("index", menu.getPath());
                    map.put("component", menu.getComponentFile());
                    Menu pMenu = menuDao.findOne(menu.getParentId());
                    if (pMenu != null) {
                        map.put("parentName", pMenu.getName());
                        map.put("parentIndex", pMenu.getGradeCode());
                    }
                }

                map.put("children", findUserHasMenu(menu.getId(), userId));
                menuList.add(map);
            }
        }
        return menuList;
    }

    /**
     * 查询作用域的顶级菜单
     *
     * @param permissionScope
     * @return
     */
    public Menu findTopMenuByScope(String permissionScope) {
        StringBuilder hql = new StringBuilder("select m  from Menu m where 1=1 ");
        hql.append(" and m.permissionScope = :permissionScope and isAdmin='super' ");
        Map<String, Object> params = new HashMap<>();
        params.put("permissionScope", permissionScope);
        List<Menu> list = this.menuDao.findList(hql.toString(), params);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 查询用户关联的权限
     *
     * @param userId
     * @return
     */
    public List<Menu> findPermissionByUserId(Long userId) {
        StringBuilder hql = new StringBuilder("select m  from Menu m,RoleMenu rm,UserRole ur where 1=1 ");
        hql.append(" and m.id=rm.menuId and rm.roleId=ur.roleId ");
        hql.append("  and ur.userId =:userId ");
        hql.append(" and  m.type='2' group by m.id  order by m.sort asc");
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        return this.menuDao.findList(hql.toString(), params);
    }

    /**
     * 查询用户查看的 右上角大屏 按钮
     *
     * @param userId
     * @return
     */
    public List<Menu> findScreenBtn(Long userId) {
        StringBuilder hql = new StringBuilder("select m  from Menu m,RoleMenu rm,UserRole ur where 1=1 ");
        hql.append(" and m.id=rm.menuId and rm.roleId=ur.roleId ");
        hql.append("  and ur.userId =:userId ");
        hql.append(" and  m.type='3' group by m.id order by m.sort asc");
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        return this.menuDao.findList(hql.toString(), params);
    }
}
